package com.foreveross.chameleonsdk;

import java.io.File;

import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import com.darin.cl.task.CLTask;
import com.darin.cl.util.CLDateUtil;
import com.darin.cl.util.CLFileUtil;
import com.foreveross.URL;
import com.foreveross.util.Preferences;
import com.foreveross.zillasdk.ZillaListener;
import com.foreveross.zillasdk.ZillaManager;

/**
 * 初始化变色龙SDK CApplicaiton、复制asset文件www/www.zip并解压www文件、应用验证功能.<br>
 * 
 * @author Jianfeng.Lao
 * 
 */
public class ChameleonSDK {
	private static final String TAG = "ChameleonSDK";
	private ChameleonInitCallBack mChameleonInitCallBack;
	private CLTask unZipTask;
	private CLTask appAuthTask;
	private boolean seekAuth = false;
	private Context mContext;

	private static ChameleonSDK mInstance;
	private CApplication mCApplication;
	private boolean reUnZipWwwFolder=false;

	private ChameleonSDK() {
	}

	public static ChameleonSDK getInstance() {
		if (mInstance == null) {
			mInstance = new ChameleonSDK();
		}
		return mInstance;
	}

	/**
	 * 跳过app验证
	 * 
	 * @param seekAuth
	 */
	public void setSeekAuth(boolean seekAuth) {
		this.seekAuth = seekAuth;
	}
	/**
	 * 检查/assets/www/www.zip解压状态和应用验证
	 * @param context
	 * @param callBack
	 */
	public void initChameleonSDK(Context context, ChameleonInitCallBack callBack) {
		this.mContext = context;
		this.mChameleonInitCallBack = callBack;
		String basePath = Environment.getExternalStorageDirectory().getPath() + "/"
				+ URL.APP_PACKAGENAME;
		// 应用是否第一次使用
		Boolean isFirstTime = Preferences.getFirsttime();
		// www.zip是否已经被解压缩
		boolean hasUnZip = true;
		// www文件夹是否存在于手机sdcard内
		File file = new File(basePath + "/www");
		if (!file.exists()) {
			hasUnZip = false;
		}
		if (isFirstTime) {
			// 第一次使用，必须解压www.zip
			hasUnZip = false;
			Preferences.saveVersionCode(getVersionCode(context));
		} else {
			int versionCode = Preferences.getVersionCode();
			if (versionCode < getVersionCode(context)) {
				// 升级应用后，重新解压www.zip覆盖旧文件
				Preferences.saveVersionCode(getVersionCode(context));
				hasUnZip = false;
			}
		}
		if (!hasUnZip||reUnZipWwwFolder) {
			// 符合解压条件，开始解压
			file.mkdirs();
			unZipTask = new UnZipWWWTask();
			getCApplication().getClTaskManager().execute(unZipTask);
		} else {
			checkAppAuthentication();
		}
	}

	/**
	 * 应用验证
	 */
	private void checkAppAuthentication() {
		if (seekAuth) {
			onAuthSuccess();
		}
		String token = Preferences.getToken();
		String expired = Preferences.getExpired();

		if (!"".equals(token)) {
			if (!"".equals(expired)) {
				long expiredLong = CLDateUtil.convert2long(expired,
						CLDateUtil.DATE_FORMAT_PATTERN_3);
				long now = System.currentTimeMillis();
				if (now < expiredLong) {
					// 应用验证未过期
					onAuthSuccess();
					return;
				}
			}
		}
		requestAppAuthentication();
	}

	public int getVersionCode(Context context) {
		PackageManager pm = context.getPackageManager();
		PackageInfo pi;
		try {
			pi = pm.getPackageInfo(context.getPackageName(), 0);
			return pi.versionCode;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return 0;
	}

	/**
	 * 请求验证
	 */
	private void requestAppAuthentication() {
		ZillaListener delegate = new ZillaListener() {

			@Override
			public void requestSuccess(String json) {
				try {
					Log.i(TAG, "json = " + json);
					if (json.equals("403") || json.equals("400")) {
						onAuthAppError(json);
					} else {
						JSONObject jb = new JSONObject(json);
						String token = jb.getString("token");
						String expired = jb.getString("expired");
						// 保存token和expired
						Preferences.saveToken(token, expired);
						onAuthSuccess();
					}

				} catch (JSONException e) {
					e.printStackTrace();
					onError(e);
				}

			}

			@Override
			public void requestStart() {

			}

			@Override
			public void requestFailed(Exception error) {
				onAuthAppError("404");
			}
		};
		appAuthTask = ZillaManager.getInstance().appAuth(mContext, delegate);
	}

	/**
	 * 取消初始化
	 */
	public void cancel() {
		if (unZipTask != null) {
			unZipTask.cancel();
		}
		if (appAuthTask != null) {
			appAuthTask.cancel();
		}
	}

	/**
	 * 跳转第一个模块
	 */
	private void onAuthSuccess() {
		if (mChameleonInitCallBack != null) {
			mChameleonInitCallBack.onSuccess();
		}
	}

	private class UnZipWWWTask extends CLTask<Void, Void, Void> {

		@Override
		public Void doInBackground(Void... params) throws Exception {
			String basePath = Environment.getExternalStorageDirectory().getPath() + "/"
					+ URL.APP_PACKAGENAME;
			boolean copySuccess = CLFileUtil.copyAssetsFile(mContext, "www/www.zip", basePath
					+ "/www/www.zip");
			if (copySuccess) {
				File fileDir = new File(basePath + "/www/");
				if (!fileDir.exists()) {
					fileDir.mkdirs();
				}
				CLFileUtil.unZipFile(basePath + "/www/www.zip", basePath + "/www/");
			}
			return null;
		}

		@Override
		protected void doOnException(Exception exception) {
			super.doOnException(exception);
			Toast.makeText(mContext, "初始化资源失败", Toast.LENGTH_SHORT).show();

		}

		@Override
		public void doOnSuccess(Void result) {
			Preferences.saveFirsttime(false);
			checkAppAuthentication();
		}

	}

	public interface ChameleonInitCallBack {
		public void onAuthAppError(String code);

		public void onError(Exception err);

		public void onSuccess();
	}
	/**
	 * 初始化CApplication
	 * @param context
	 * @param chameleonJson 默认放在assets/Chameleon.json
	 * @param chameleonPropreties 默认放在assets/Chameleon.properties
	 */
	public void initCApplication(Context context,String chameleonJson,String chameleonPropreties) {
		this.mContext = context;
		Preferences.getInstance(context);
		mCApplication=new CApplication(context, chameleonJson,chameleonPropreties);
		mCApplication.onCreate();
	}

	private void onError(Exception exception) {
		if (mChameleonInitCallBack != null) {
			mChameleonInitCallBack.onError(exception);
		}
	}

	private void onAuthAppError(String code) {
		if (mChameleonInitCallBack != null) {
			mChameleonInitCallBack.onAuthAppError(code);
		}
	}
	
	/**
	 * 如果设置true,会重新解压assets/www/www.zip包
	 * @param isUnZipAgain
	 */
	public void setReUnZipWwwFolder(boolean isUnZipAgain){
		this.reUnZipWwwFolder=isUnZipAgain;
	}

	public static CApplication getCApplication() {
		return getInstance().mCApplication;
	}
	

	
}
